package dnet

import (
	"dgo/goutils/utils"
	"net"
	"sync/atomic"
)

type DNetFileServ struct {
	onlinecnt            int32
	listener             *NetListener
	onlinelst            utils.GSyncMapGroup
	OnListenSucc         func(network, addr string)
	AuthEvent            func(conn *DNetFileServConnHandler, usr, pass string) bool
	GetRealFileNameEvent func(conn *DNetFileServConnHandler, cmd string, filename string) (realfilename string)
}

func NewDNetFileServ() *DNetFileServ {
	rval := &DNetFileServ{
		listener: NewNetListener(),
	}
	rval.init()
	return rval
}

func (this *DNetFileServ) init() {
	this.listener.OnListenSucc = func(network, addr string) {
		if this.OnListenSucc != nil {
			this.OnListenSucc(network, addr)
		}
	}
	this.listener.HandleConnFunc = func(conn net.Conn) {
		go this.innerHandleConnFunc(conn)
	}
}

func (this *DNetFileServ) GetStoreFileBlock() int64 {
	return 980
}

/*
**
下载时读取的文件大小
*/
func (this *DNetFileServ) GetDownFileBlock() int64 {
	return 980
}

func (this *DNetFileServ) GetRealFileName(conn *DNetFileServConnHandler, cmd string, filename string) (realfilename string) {
	if this.GetRealFileNameEvent != nil {
		return this.GetRealFileNameEvent(conn, cmd, filename)
	}
	return
}

func (this *DNetFileServ) ConfigAddr(addr string) {
	this.listener.Config("tcp", addr)
}

func (this *DNetFileServ) Start() {
	this.listener.CheckStart()
}

func (this *DNetFileServ) Stop() {
	this.listener.Close()
}

func (this *DNetFileServ) innerHandleConnFunc(conn net.Conn) {
	if utils.GoFunCatchException {
		defer utils.PanicHandler()
	}

	handler := NewFileServConnHandler(this, conn)
	this.onlinelst.Set(handler, handler)
	atomic.AddInt32(&this.onlinecnt, 1)
	defer func() {
		atomic.AddInt32(&this.onlinecnt, -1)
		this.onlinelst.Remove(handler)
	}()

	handler.clientHandleEntry()
}
